package com.yakaten.login;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.CookieHandler;
import java.net.CookiePolicy;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.yakaten.dto.RakutenLoginDto;

public class RakutenLogin {

	private static final String LOGIN_URL_STEP0 = "https://glogin.rms.rakuten.co.jp/?sp_id=1";

	private static final String LOGIN_URL_STEP1 = "https://glogin.rms.rakuten.co.jp/";

	private static final String LOGIN_URL_STEP2 = "https://glogin.rms.rakuten.co.jp/";

	private static final String LOGIN_URL_STEP3 = "https://glogin.rms.rakuten.co.jp/";

	private static final String LOGIN_URL_STEP4 = "https://mainmenu.rms.rakuten.co.jp/?act=login&sp_id=1";

	private static final String LOGIN_URL_STEP5 = "https://mainmenu.rms.rakuten.co.jp/";

	private static final String LOGIN_URL_STEP6 = "https://item.rms.rakuten.co.jp/rms/mall/rsf/item/vc?__event=RI00_001_101";

	// <input type="hidden" name="business_id"
	// value="a8ae6c349c0caa5ff387ec82fd10b77b675266">
	private static final String REGEX_module = "<input type=\"hidden\" name=\"module\" value=\"(.+?)\">";

	// <input type="hidden" name="business_id"
	// value="a8ae6c349c0caa5ff387ec82fd10b77b675266">
	private static final String REGEX_action = "<input type=\"hidden\" name=\"action\" value=\"(.+?)\">";

	private static final String REGEX_biz_login_id = "<input type=\"hidden\" name=\"biz_login_id\" value=\"(.+?)\">";
	// <input type="hidden" name="business_id"
	// value="a8ae6c349c0caa5ff387ec82fd10b77b675266">
	protected static final String REGEX_business_id = "<input type=\"hidden\" name=\"business_id\" value=\"(.+?)\">";

	// <input type="hidden" name="__suid" value="r1375151544ffe5d6db4751login">
	private static final String REGEX___suid = "<input type=\"hidden\" name=\"__suid\" value=\"(.+?)\">";

	// <img
	// src="https://item.rms.rakuten.co.jp/rms/mall/rsf/item/login?r=cc730993&amp;t=MTM0MjE3MjQ2NiYxMzQyMTcyNjQ2JjJlNzc4NTY2"
	// width="1" height="1">
	// private static final String
	// REGEX_LOGIN_URL="<img src=\"(https.+?r=.+?t=.+?)\"";
	private static final String REGEX_LOGIN_URL = "<img src=\"(https://item.rms.rakuten.co.jp/rms/mall/rsf/item/login.+?)\"";

	// <table width=8 height=4 border=0 cellspacing=0 cellpadding=0><tr><td>
	private static final String REGEX_LOGIN_TABLE_AREA = "<table width=8 height=4 border=0 cellspacing=0 cellpadding=0><tr><td>(.+?)</td>";

	private static final Pattern PATTERN_module = Pattern
			.compile(REGEX_module);

	private static final Pattern PATTERN_action = Pattern
			.compile(REGEX_action);

	private static final Pattern PATTERN_biz_login_id = Pattern
			.compile(REGEX_biz_login_id);

	private static final Pattern PATTERN_business_id = Pattern
			.compile(REGEX_business_id);

	private static final Pattern PATTERN___suid = Pattern
			.compile(REGEX___suid);

	private static final Pattern PATTERN_LOGIN_URL = Pattern
			.compile(REGEX_LOGIN_URL);

	private static final Pattern PATTERN_LOGIN_TABLE_AREA = Pattern
			.compile(REGEX_LOGIN_TABLE_AREA);

	private RakutenLoginDto doLoginStep0(RakutenLoginDto loginDto) {
		BufferedReader bufferedReader = null;
		HttpURLConnection connection = null;
		try {
			URL loginUrl = new URL(LOGIN_URL_STEP0);

			connection = (HttpURLConnection) loginUrl.openConnection();

			connection.connect();
			InputStream urlStream = connection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(
					urlStream, "euc-jp"));
			String ss = null;
			StringBuffer total = new StringBuffer();
			while ((ss = bufferedReader.readLine()) != null) {
				total.append(ss);
			}

			Matcher matcherbiz_module = PATTERN_module.matcher(total);
			if (matcherbiz_module.find()) {
				String module = matcherbiz_module.group(1);
				loginDto.setModule(module);
			}

			Matcher matcherbiz_action = PATTERN_action.matcher(total);
			if (matcherbiz_action.find()) {
				String action = matcherbiz_action.group(1);
				loginDto.setAction(action);
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return loginDto;
	}

	private RakutenLoginDto doLoginStep1(RakutenLoginDto loginDto) {
		OutputStreamWriter out = null;
		BufferedReader bufferedReader = null;
		HttpURLConnection connection = null;
		try {
			URL loginUrl = new URL(LOGIN_URL_STEP1);
			Locale.setDefault(Locale.US);

			connection = (HttpURLConnection) loginUrl.openConnection();

			connection.setDoOutput(true);

			out = new OutputStreamWriter(connection.getOutputStream(), "euc-jp");

			out.write("sp_id=" + loginDto.getSp_id() + "&module="
					+ loginDto.getModule() + "&action=" + loginDto.getAction()
					+ "&login_id=" + loginDto.getLogin_id() + "&passwd="
					+ loginDto.getPasswd() + "&submit=" + loginDto.getSubmit());

			out.flush();

			InputStream urlStream = connection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(
					urlStream, "euc-jp"));
			String ss = null;
			StringBuffer total = new StringBuffer();
			while ((ss = bufferedReader.readLine()) != null) {
				total.append(ss);
			}

			Matcher matcherbiz_login_id = PATTERN_biz_login_id.matcher(total);
			if (matcherbiz_login_id.find()) {
				String biz_login_id = matcherbiz_login_id.group(1);
				loginDto.setBiz_login_id(biz_login_id);
			}

			Matcher matcherbusiness_id = PATTERN_business_id.matcher(total);
			if (matcherbusiness_id.find()) {
				String business_id = matcherbusiness_id.group(1);
				loginDto.setBusiness_id(business_id);
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}

		return loginDto;
	}

	private RakutenLoginDto doLoginStep2(RakutenLoginDto loginDto) {
		OutputStreamWriter out = null;
		BufferedReader bufferedReader = null;
		HttpURLConnection connection = null;

		try {
			URL loginUrl = new URL(LOGIN_URL_STEP2);
			connection = (HttpURLConnection) loginUrl.openConnection();

			connection.setDoOutput(true);

			out = new OutputStreamWriter(connection.getOutputStream(), "euc-jp");

			String param = "sp_id=" + loginDto.getSp_id() + "&module="
					+ loginDto.getModule() + "&action=" + loginDto.getAction()
					+ "&biz_login_id=" + loginDto.getBiz_login_id()
					+ "&business_id=" + loginDto.getBusiness_id() + "&user_id="
					+ loginDto.getUser_id() + "&user_passwd="
					+ loginDto.getUser_passwd() + "&submit="
					+ loginDto.getSubmit();

			out.write(param);
			out.flush();

			InputStream urlStream = connection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(
					urlStream, "euc-jp"));
			String ss = null;
			StringBuffer total = new StringBuffer();
			while ((ss = bufferedReader.readLine()) != null) {
				total.append(ss);
			}

			Matcher matcherbiz___suid = PATTERN___suid.matcher(total);
			if (matcherbiz___suid.find()) {
				String __suid = matcherbiz___suid.group(1);
				loginDto.set__suid(__suid);
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}

		return loginDto;
	}

	private RakutenLoginDto doLoginStep3(RakutenLoginDto loginDto) {
		OutputStreamWriter out = null;
		HttpURLConnection connection = null;
		try {
			URL loginUrl = new URL(LOGIN_URL_STEP3);
			connection = (HttpURLConnection) loginUrl.openConnection();

			connection.setDoOutput(true);

			out = new OutputStreamWriter(connection.getOutputStream(), "euc-jp");

			String para = "module=" + loginDto.getModule() + "&action="
					+ loginDto.getAction() + "&__suid=" + loginDto.get__suid()
					+ "&submit=" + loginDto.getSubmit();

			out.write(para);
			out.flush();

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (connection != null) {
				connection.disconnect();
			}
		}
		return loginDto;
	}

	private RakutenLoginDto doLoginStep4(RakutenLoginDto loginDto) {
		InputStream urlStream = null;
		HttpURLConnection connection = null;
		try {
			URL loginUrl = new URL(LOGIN_URL_STEP4);

			connection = (HttpURLConnection) loginUrl.openConnection();

			connection
					.setRequestProperty("User-Agent",
							"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1");

			connection.connect();
			urlStream = connection.getInputStream();

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (urlStream != null) {
				try {
					urlStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (connection != null) {
				connection.disconnect();
			}
		}

		return loginDto;
	}

	private RakutenLoginDto doLoginStep5(RakutenLoginDto loginDto) {
		OutputStreamWriter out = null;
		BufferedReader bufferedReader = null;
		HttpURLConnection connection = null;
		try {
			URL loginUrl = new URL(LOGIN_URL_STEP5);

			connection = (HttpURLConnection) loginUrl.openConnection();
			connection.setDoOutput(true);
			out = new OutputStreamWriter(connection.getOutputStream(), "euc-jp");
			out.write("submit=" + loginDto.getSubmit());
			out.flush();

			InputStream urlStream = connection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(
					urlStream, "UTF-8"));
			String ss = null;
			StringBuffer total = new StringBuffer();
			while ((ss = bufferedReader.readLine()) != null) {
				total.append(ss);
			}

			String biz_login_table_area = "";
			Matcher matcherbiz_login_table_area = PATTERN_LOGIN_TABLE_AREA
					.matcher(total);
			if (matcherbiz_login_table_area.find()) {
				biz_login_table_area = matcherbiz_login_table_area.group(1);
			}

			Matcher matcherbiz_login_url = PATTERN_LOGIN_URL
					.matcher(biz_login_table_area);
			while (matcherbiz_login_url.find()) {
				String rmsLoginUrl = matcherbiz_login_url.group(1);
				loginDto.getRmsLoginUrl().add(rmsLoginUrl);
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (connection != null) {
				connection.disconnect();
			}
		}

		return loginDto;
	}

	private RakutenLoginDto doLoginRmsLogin(RakutenLoginDto loginDto) {
		try {
			List<String> loginUrlList = loginDto.getRmsLoginUrl();
			Iterator<String> loginUrlIt = loginUrlList.iterator();

			while (loginUrlIt.hasNext()) {
				URL rmsLoginUrl = new URL(loginUrlIt.next());
				HttpURLConnection rmsLoginConnection = (HttpURLConnection) rmsLoginUrl
						.openConnection();
				rmsLoginConnection.connect();

				rmsLoginConnection.getHeaderField("Set-Cookie");
				rmsLoginConnection.disconnect();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

		}

		return loginDto;
	}

	private RakutenLoginDto doLoginStep6(RakutenLoginDto loginDto) {
		HttpURLConnection connection = null;
		try {

			URL loginUrl = new URL(LOGIN_URL_STEP6);

			connection = (HttpURLConnection) loginUrl.openConnection();

			connection.connect();

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
		}
		return loginDto;
	}

	/**
	 * 
	 * @param loginId
	 * @param passwd
	 * @param user_id
	 * @param user_passwd
	 * @return
	 */
	public boolean doLogin(String loginId,String passwd,String user_id,String user_passwd) {

		CorrectedCookieManager manager = new CorrectedCookieManager();
		manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
		CookieHandler.setDefault(manager);

		RakutenLogin rl = new RakutenLogin();
		RakutenLoginDto loginDto = new RakutenLoginDto();
		loginDto.setSp_id("1");
		loginDto = rl.doLoginStep0(loginDto);

		loginDto.setLogin_id(loginId);
		loginDto.setPasswd(passwd);

		loginDto = rl.doLoginStep1(loginDto);

		loginDto.setAction("BizAuthUserAttest");
		loginDto.setUser_id(user_id);
		loginDto.setUser_passwd(user_passwd);
		loginDto = rl.doLoginStep2(loginDto);

		loginDto.setAction("BizAuthAnnounce");
		loginDto = rl.doLoginStep3(loginDto);

		loginDto = rl.doLoginStep4(loginDto);

		loginDto = rl.doLoginStep5(loginDto);

		loginDto = rl.doLoginRmsLogin(loginDto);

		loginDto = rl.doLoginStep6(loginDto);

		return true;
	}

	public static void main(String[] args) {
		CorrectedCookieManager manager = new CorrectedCookieManager();
		manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
		CookieHandler.setDefault(manager);

		RakutenLogin rl = new RakutenLogin();
		RakutenLoginDto loginDto = new RakutenLoginDto();
		loginDto.setSp_id("1");
		loginDto = rl.doLoginStep0(loginDto);

		loginDto.setLogin_id("speedcomtech");
		loginDto.setPasswd("visa1357");
		loginDto.setSubmit("楽天会員の認証へ");

		loginDto = rl.doLoginStep1(loginDto);

		loginDto.setSubmit("%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3");
		loginDto.setAction("BizAuthUserAttest");
		loginDto.setUser_id("hanjianfeng@hotmail.com");
		loginDto.setUser_passwd("visa1357");
		loginDto = rl.doLoginStep2(loginDto);

		loginDto
				.setSubmit("%E3%80%80%E3%80%80%E3%80%80%E6%AC%A1%E3%81%B8%E3%80%80%E3%80%80%E3%80%80");
		loginDto.setAction("BizAuthAnnounce");
		loginDto = rl.doLoginStep3(loginDto);

		loginDto = rl.doLoginStep4(loginDto);

		loginDto.setSubmit("上記を遵守していることを確認の上、RMSを利用します");
		loginDto = rl.doLoginStep5(loginDto);

		loginDto = rl.doLoginRmsLogin(loginDto);

		loginDto = rl.doLoginStep6(loginDto);

	}
}
